﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using VSDBM.Code.dao;
using VSDBM.Code.dto;
using VSDBM.Code.functions;
using System.Threading;
using System.Text;

public partial class Visual_Procedures_Subtyping_SequenceSubtyping : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
           
            FillOrganism();
        }
    }

    protected void FillOrganism()
    {
        DataSet ds = OrganismDAO.select("WHERE status=1", "ORDER BY name");
        //verifica erro na querry
        if (ds.Tables.Count == 0)
        {
            Exception ex = new Exception("Table not found!");
            throw ex;
        }
        //verifica se existem organismos cadastrados.
        else if (ds.Tables[0].Rows.Count == 0)
        {
            DataRow dr = ds.Tables[0].NewRow();
            ds.Tables[0].Rows.InsertAt(dr, 0);
            ds.Tables[0].Rows[0]["name"] = "NO ORGANISMS FOUND";
            ds.Tables[0].Rows[0]["id"] = "0";

        }
        //Insere os organismos no Dropdown List(ddOrganism).

        ddOrganism.DataSource = ds.Tables[0];
        ddOrganism.DataTextField = "name";
        ddOrganism.DataValueField = "id";
        ddOrganism.DataBind();
        
        ddOrganism.Visible = true;

    }
  

    protected void btnStart_Click(object sender, EventArgs e)
    {
        VSDBM.Code.dto.User usuariologado = (VSDBM.Code.dto.User)HttpContext.Current.Session["usuariologado"];
        lblDone.Visible = false;
        //start subtype here.
        
            if (ddOrganism.SelectedValue == "0")
            {
                HttpContext.Current.Session["exception"] = "No Organism found.";
                Response.Redirect("../../../Visual/Errors/error.aspx");
            }
            else
            {
                //SubtypeOrganism(Convert.ToInt32(ddOrganism.SelectedValue));
                //Cria Jobcode.
                String codeprepair = usuariologado.name;
                codeprepair += Convert.ToString(ddOrganism.SelectedValue);
                codeprepair += Convert.ToString(new Random().Next());
                String JobId = Encryption.CalculateMD5Hash(codeprepair);
                

                //fim da inserção de parâmetros(o último parâmetro é a quantidade de sequências que serão subtipadas paralelamente)
                SubtypingProcess Subtyping = new SubtypingProcess(Convert.ToInt32(ddOrganism.SelectedValue), usuariologado.id, JobId, 25);

                //prepara o ThreadStarter para iniciar a thread.
               ParameterizedThreadStart Starter = new ParameterizedThreadStart(paralelStart);
                //Instancia a thread e aponta para o threadstarter.
               Thread SubtypeThread = new Thread(Starter);
                //inicia a thread passando os parâmetros necessários.
                SubtypeThread.Start(Subtyping);
               //armazena mensagem de "Done" na session do usuário.
                HttpContext.Current.Session["done"] = "Process started. <br> We will send you a message when it finishes. <br><br> Job Code: " + JobId + "<br>";
                //Redireciona o usuário para a página de "DONE"
                Response.Redirect("../../../Visual/Done/Done.aspx");

            }
       

        
    }


    public void paralelStart(Object Process)
    {
        SubtypingProcess subprocess = Process as SubtypingProcess;
        subprocess.runMethod();
    }

   /* //método que subtipa o organismo.
   
    public void SubtypeOrganism(Object Parametros)
    {
        System.DateTime startTime = DateTime.Now;
        //Transforma o parametro da thread em lista.
        List<String> parameterlist = Parametros as List<String>;
        //Obtém o ID do organismo para subtipar.
        int OrganismId = Convert.ToInt32(parameterlist[0]);
        //Obtém id do usuário que iniciou a thread.
        int UserId = Convert.ToInt32(parameterlist[1]);
        //Obtém o JobID da thread.
        String JobId = parameterlist[2];
        //prepara o relatório final da thread
        StringBuilder reportBuilder = new StringBuilder();
        //armazena título da thread no relatório
        reportBuilder.Append("Organism Subtype Report");
        //armazena "pula linha"
        reportBuilder.Append(" \r\n");
        //prepara lista de sequências a serem subtipadas
        List<Sequence> sequenceList = new List<Sequence>();
        //Prepara a lista de referências dos subtipos
        List<String[]> subReferenceList = new List<string[]>();
        //Preenche lista de sequências a serem subtipadas
        sequenceList = SequenceDAO.DStoList(SequenceDAO.select("WHERE idorganism =" + OrganismId, ""));
        //Obtém referência de subtipo, juntamente com o id do SUBTIPO.
        DataSet dsubtype = SubtypeDAO.select("WHERE idorganisms =" + OrganismId, "");
        bool majorerror = false;
        if (dsubtype.Tables[0].Rows.Count == 0)
        {

            reportBuilder.Append("MAJOR ERROR");
            reportBuilder.Append(" \r\n");
            reportBuilder.Append("ERROR MESSAGE: There is no subtype for the organism on DataBase.");
            reportBuilder.Append(" \r\n");
            reportBuilder.Append(" \r\n");
            reportBuilder.Append("----  THREAD ABORTED ----");
            majorerror = true;
        }
        else
        {
            
            foreach (DataRow row in dsubtype.Tables[0].Rows)
            {
                DataSet drefsubtype = Subtype_ReferenceDAO.select("WHERE idsubtype=" + Convert.ToInt32(row["id"]), "");

                foreach (DataRow refrow in drefsubtype.Tables[0].Rows)
                {
                    String[] auxiliar1 = new string[2];
                    auxiliar1[0] = row["id"].ToString();
                    List<Sequence> listaauxiliar = SequenceDAO.DStoList(SequenceDAO.select("WHERE id=" + refrow["idsequence"], ""));
                    auxiliar1[1] = listaauxiliar[0].sequence;
                    subReferenceList.Add(auxiliar1);
                }


            }
       
        }
        //Fim das obtenções

        //contagem de sucessos.
        int sucesscount = 0;
        //contagem de empates.
        int empatecount = 0;
        //prepara relatório de empares.
        StringBuilder empates = new StringBuilder();
        empates.Append("TIED SCORE REPORT");
        empates.Append(" \r\n");
       if(!majorerror){
       
           
        //inicia o processo de comparação de sequências para a subtipagem. Para cada sequência a ser subtipada, seguiremos os passos a seguir:
         
           foreach (Sequence querry in sequenceList)
        {

            //inicializa melhor score
            float bestscore = 0;
            //inicializa a variável que indica o id do belhor score
            int subtypeid = 0;
            //compara a sequência com cada referência disponível.
            foreach (String[] reference in subReferenceList)
            {
                String referencesequence = reference[1];
                String querrysequence = querry.sequence;
                float actualScore = 0;
                //realiza alinhamentos

                Sequence database = new Sequence();
                database.sequence = referencesequence.ToUpper().Replace("\r\n", "").Replace(" ", "");
                querry.sequence = querry.sequence.ToUpper().Replace("\r\n", "").Replace(" ", "");
                SmithWatermanMMF swmmf = new SmithWatermanMMF(database, querry, new SubstitutionMatrix(), false);
                actualScore = swmmf.highScore;

                if (bestscore < actualScore)
                {
                    bestscore = actualScore;
                    subtypeid = Convert.ToInt32(reference[0]);
                    //score melhor que o anterior
                }

                System.GC.Collect();
            }

            //armazena a subtipagem desta sequencia
            Sequence_SubtypeDAO.add(new Sequence_Subtype(0, querry.id, subtypeid, bestscore));
            
        }
           
        }
        if (!majorerror)
        {
            String elapsed = DateTime.Now.Subtract(startTime).ToString(@"hh\:mm\:ss\.FF");
            reportBuilder.Append("--- Job Finished! ---");
            reportBuilder.Append(" \r\n");
            reportBuilder.Append("Time elapsed: "+elapsed);
            reportBuilder.Append(" \r\n");
            reportBuilder.Append(sucesscount.ToString() + " sequences subtyped.");
            reportBuilder.Append(" \r\n");
            reportBuilder.Append(empatecount.ToString() + " tied scores.");
            reportBuilder.Append(" \r\n");
            if (empatecount > 0)
            {
                reportBuilder.Append(" \r\n");
                reportBuilder.Append(empates.ToString());
            }
        }
        //Envia mensagem com o report.
        Message msg = new Message();
        msg.senduserid = UserId;
        msg.touserid = UserId;
        msg.title = "Job: " + JobId;
        msg.message = reportBuilder.ToString();
        MessageDAO.sendMessage(msg);
    }
    */
   
 
}